package com.rightrule.rule.executor.node;

import com.googlecode.aviator.Expression;
import com.googlecode.aviator.exception.ExpressionRuntimeException;
import com.rightrule.rule.compile.AviatorCompiledInstance;
import com.rightrule.rule.compile.Compilable;
import com.rightrule.rule.compile.CompilableInstance;
import com.rightrule.rule.constans.CommonConstant;
import com.rightrule.rule.executor.RuntimeContext;
import com.rightrule.rule.response.NodeExecutionResponse;
import com.rightrule.rule.utils.ScriptUtils;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;

import java.util.Map;

/**
 *  分支节点
 */
@Data
@Slf4j
public class BranchNode extends BaseNode implements Compilable {

    @Override
    public CompilableInstance compile() {
        for (NextNode nextNode : getNextNodes()) {
            Expression expression = ScriptUtils.compileAviatorScript(nextNode.getExpression());
            nextNode.setCompilableInstance(new AviatorCompiledInstance(expression));
        }
        return getNextNodes().get(0).getCompilableInstance();
    }

    @Override
    public NodeExecutionResponse execute(RuntimeContext context, Map<String, Object> variableMap) {
        NodeExecutionResponse baseExecutionResponse = new NodeExecutionResponse();
        int nextNodeIndex = -1;
        // 查找符合条件的分支
        try {
            for (NextNode nextNode : getNextNodes()) {
                nextNodeIndex++;
                if ((boolean) nextNode.getCompilableInstance().execute(variableMap)) {
                    break;
                }
            }
        } catch (ExpressionRuntimeException e) {
            baseExecutionResponse.setExecuteStaus(CommonConstant.EXECUTE_BRANCH_FAIL);
            log.error("execute branch ExpressionRuntimeException error ,context={},variableMap={}", context, variableMap);
        } catch (Throwable e) {
            baseExecutionResponse.setExecuteStaus(CommonConstant.EXECUTE_BRANCH_FAIL);
            log.error("execute branch Throwable error ,context={},variableMap={}", context, variableMap);
        }

        baseExecutionResponse.setNextNodeIndex(nextNodeIndex);
        // 如果走到了异常分支，则执行异常
        if (nextNodeIndex < 0 || nextNodeIndex >= getNextNodes().size()) {
            baseExecutionResponse.setExecuteStaus(CommonConstant.EXECUTE_BRANCH_FAIL);
        }

        return baseExecutionResponse;
    }
}
